<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>drag</title>
</head>
<style>
    body {
        margin-top: 10%;
        text-align: center;
    }

    canvas {
        left: 0;
        top: 0;
        background: #ddd;
    }
</style>

<body>
    <div>
        <input type="color"></input>
    </div>
    <canvas></canvas>
</body>
<script>
    const colorPocker = document.querySelector('input')
    const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')

    const shapes = []

    function initCanvas() {
        const w = 500, h = 300
        canvas.width = w * devicePixelRatio
        canvas.height = h * devicePixelRatio

        canvas.style.width = w + 'px'
        canvas.style.height = h + 'px'
        canvas.style.color = '#000'
    }

    class rectangle {
        constructor(color, startX, startY) {
            this.color = color
            this.startX = startX
            this.startY = startY
            this.endX = startX
            this.endY = startY
        }

        get minX() {
            return Math.min(this.startX, this.endX)
        }

        get maxX() {
            return Math.max(this.startX, this.endX)
        }

        get minY() {
            return Math.min(this.startY, this.endY)
        }

        get maxY() {
            return Math.max(this.startY, this.endY)
        }

        draw() {
            ctx.beginPath()
            ctx.moveTo(this.minX * devicePixelRatio, this.minY * devicePixelRatio)
            ctx.lineTo(this.maxX * devicePixelRatio, this.minY * devicePixelRatio)
            ctx.lineTo(this.maxX * devicePixelRatio, this.maxY * devicePixelRatio)
            ctx.lineTo(this.minX * devicePixelRatio, this.maxY * devicePixelRatio)
            ctx.lineTo(this.minX * devicePixelRatio, this.minY * devicePixelRatio)
            ctx.fillStyle = this.color
            ctx.fill()
            ctx.strokeStyle = '#fff'
            ctx.lineCap = 'square'
            ctx.lineWidth = 3 * devicePixelRatio
            ctx.stroke()
        }

        isInside(x, y) {
            return (x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY)
        }
    }

    initCanvas()

    // const rect = new rectangle('#a33', 0, 0)
    // rect.endX = 200
    // rect.endY = 300
    // rect.draw()

    canvas.onmousedown = (e) => {
        const rect = canvas.getBoundingClientRect()
        const clickX = e.clientX - rect.left
        const clickY = e.clientY - rect.top
        const shape = getShape(clickX, clickY)
        if (shape) {
            // 拖动
            const { startX, startY, endX, endY } = shape
            console.log(shape, startX, startY, endX, endY)
            window.onmousemove = (e) => {
                const disX = e.clientX - rect.left - clickX
                const disY = e.clientY - rect.top - clickY
                console.log(disX, disY)
                shape.startX = startX + disX
                shape.endX = endX + disX
                shape.startY = startY + disY
                shape.endY = endY + disY
                console.log(shape)
            }
        } else {
            // 新增
            const shape = new rectangle(colorPocker.value, clickX, clickY)
            shapes.push(shape)
            window.onmousemove = (e) => {
                shape.endX = e.clientX - rect.left
                shape.endY = e.clientY - rect.top
            }

        }

        window.onmouseup = (e) => {
            window.onmousemove = null
            window.onmouseup = null
        }
    }

    // 判断当前鼠标位置是否是选中已存在的图形（从后往前遍历，优先选择后面绘制的）
    function getShape(x, y) {
        for (let i = shapes.length - 1; i >= 0; i--) {
            const shape = shapes[i]
            if (shape.isInside(x, y)) {
                return shape
            }
        }
        return null
    }

    // 优化空间：当进行了鼠标操作事件是才调用重绘
    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        shapes.forEach(item => {
            item.draw()
        })
        requestAnimationFrame(draw)
    }

    document.addEventListener('keydown', function (event) {
        // 判断是否按下了 ctrl+z 组合键
        if (event.ctrlKey && event.keyCode === 90) {
            console.log('执行了 Undo 操作');
            shapes.pop()
        }
    });

    draw()
</script>

</html>